package com.zjl.SpringBoot.第03章_Web开发.H_全面接管MVC;

import com.zjl.SpringBoot.第03章_Web开发.B_web实现逻辑;
import com.zjl.SpringBoot.第03章_Web开发.C_静态资源配置.C1_静态资源默认;
import com.zjl.SpringBoot.第03章_Web开发.E_内容协商.MyConfig;
import com.zjl.SpringBoot.第03章_Web开发.G_嵌入式容器.G0_自动配置;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.web.WebProperties;
import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration;
import org.springframework.context.annotation.Configuration;
import org.springframework.format.support.FormattingConversionService;
import org.springframework.stereotype.Service;
import org.springframework.validation.Validator;
import org.springframework.web.accept.ContentNegotiationManager;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.support.ConfigurableWebBindingInitializer;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.filter.RequestContextFilter;
import org.springframework.web.servlet.FlashMapManager;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.View;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
import org.springframework.web.servlet.view.BeanNameViewResolver;
import org.springframework.web.servlet.view.ContentNegotiatingViewResolver;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;

/**
 * @EnableWebMvc //禁用所有 web的自动配置
 *      {@link WebMvcAutoConfiguration}
 *          1.{@link WebMvcAutoConfiguration.WebMvcAutoConfigurationAdapter}
 *                  继承了 {@link WebMvcConfigurer} 定义了 mvc底层组件
 *                   详解  {@link B_web实现逻辑}   //提供了SpringMVC 底层所有的组件入口
 *                   详解  {@link H1_WebMvcConfigurer的功能详解}
 *                 1).{@link InternalResourceViewResolver} //视图解析器  内部跳转
 *                 2).{@link BeanNameViewResolver} 视图名（controller 返回的字符串（会跳转到 templates的 html页面））
 *                      {@link MyView}
 *                 3).{@link ContentNegotiatingViewResolver} //内容协商
 *                 4).{@link RequestContextFilter}
 *                          //请求上下文的过滤器 再任意位置获取请求
 *                          的 doFilterInternal 前后端的 请求和响应都放进去了
 *                          底层就是用 {@link RequestContextHolder} 的  {@link ThreadLocal} 实现的
 *                 5).{@link WebMvcAutoConfiguration.ProblemDetailsErrorHandlingConfiguration}
 *                      {@link org.springframework.boot.autoconfigure.web.servlet.ProblemDetailsExceptionHandler} // 有  @ControllerAdvice 处理异常
 *                      继承了 {@link ResponseEntityExceptionHandler} 发现他可以处理一些指定的异常
 *                      和处理一些对错误数据的处理和数据的返回
 *                              SpringMVC内部的异常
 *                          //错误详情
 *
 *
 *          2.{@link WebMvcAutoConfiguration.EnableWebMvcConfiguration}
 *                 详解  {@link C1_静态资源默认} //欢迎页配置  模版引擎目录，静态资源 等等
 *                  1).{@link LocaleResolver} //国际化
 *                  2).{@link org.springframework.web.servlet.ThemeResolver} //主题解析器
 *                  3).{@link FlashMapManager} //临时数据共享
 *                  4).{@link FormattingConversionService} //数据格式化，类型转换
 *                          见配置文件
 *                          spring.mvc.format.date=yyyy-MM-dd
 *                          spring.mvc.format.time=HH:mm:ss.SSS
 *                  5).{@link Validator} //数据校验
 *                  6).{@link ConfigurableWebBindingInitializer} //数据绑定   请求参数的封装与绑定
 *                  7).{@link RequestMappingHandlerMapping} //找到每个请求的映射关系
 *                  8).{@link ExceptionHandlerExceptionResolver} //默认的异常解析器
 *                  9).{@link ContentNegotiationManager} //内容协商管理器
 *
 * {@link WebMvcConfigurer} 组件：定义 MVC 底层行为   案例见{@link MyConfig}
 *
 *
 *
 * @see org.springframework.web.servlet.config.annotation.WebMvcConfigurer
 * @see org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport
 * @see org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration
 *
 */
//@EnableWebMvc //禁用所有 web的自动配置
@SpringBootApplication(
        exclude = {DataSourceAutoConfiguration.class}
)
@RestController
public class H0_EnableWebMvc原理 {
    public static void main(String[] args) {
        System.setProperty("spring.profiles.active","tomcat");//  同理 --spring.profiles.active=xxx

        SpringApplication.run(H0_EnableWebMvc原理.class, args);
        System.err.println("***********启动完毕**当前编码:" + Charset.defaultCharset().name() + "****************");

    }
    @Autowired
    请求上下文 qqq;

    @GetMapping("/**")//默认 返回 JSON
    public Object hello(HttpServletRequest request,HttpServletResponse response){

        qqq.上下文();

        return "测试请求上下文";
    }
}
@Configuration
class MyView implements View {

    @Override
    public void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
        response.getWriter().write("我是自定义的视图解析器");//
    }
}
@Service
class 请求上下文{
    public void 上下文(){
        //看源码就是将数据  放入 ThreadLocal  线程独有数据中
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        HttpServletResponse response = requestAttributes.getResponse();

    }
}
